/**
* @file scene_manager.h
* @brief 地图管理器
*/
#ifndef _SERVICE_SCENE_MANAGER_H_
#define _SERVICE_SCENE_MANAGER_H_

#include <unordered_map>
#include "../share/common_singleton.h"
#include "scene_instance.h"

class CSceneConfig
{
public:
	CSceneConfig()
	{
		scene_id_ = 0;
		base_line_ = 0;
		max_line_ = 0;
		max_player_count_ = 0;
		threshold_ = 0;
	}
	int32_t scene_id() { return scene_id_; }
	int32_t base_line() { return base_line_; }
	int32_t max_line() { return max_line_; }
	int32_t max_player_count() { return max_player_count_; }
	int32_t threshold() { return threshold_; }
public:
	int32_t scene_id_;			 //场景id;
	int32_t base_line_;			 //基础线的个数
	int32_t max_line_;			 //最大线个数;
	int32_t max_player_count_;	 //最大人数
	int32_t threshold_;			 //扩充线的阈值
};

class CSceneConfigList
{
public:
	std::vector<CSceneConfig> scene_list_;
};


class CLine
{
public:
	CLine()
	{
		line_id_ = 0;
		instance_id_ = 0;
		player_count_ = 0;
		service_id_ = 0;
		service_start_flag_ = 0;
	}

	~CLine()
	{
	}

	void set_line_id(int32_t line_id) { line_id_ = line_id; }
	int32_t line_id() const { return line_id_; }

	void set_instance_id(int64_t instance_id) { instance_id_ = instance_id; }
	int64_t instance_id() const { return instance_id_; }

	void set_player_count(int32_t player_count) { player_count_ = player_count; }
	int32_t player_count() const { return player_count_; }

	void set_service_id(int32_t service_id) { service_id_ = service_id; }
	int32_t service_id() const { return service_id_; }


private:
	int32_t line_id_;
	int32_t service_id_;
	int32_t service_start_flag_;
	int64_t instance_id_;
	int32_t player_count_;
};

class CMainScene
{
public:
	CMainScene() {
		scene_id_ = 0;
	}
	typedef std::unordered_map< int32_t, CLine > TLineMap;
public:
	void set_config(const CSceneConfig& cfg);
	CLine* CreateLine();

	CLine* GetLine(int32_t line_id);

	CLine* ChooseLine(int32_t suggest_line);
	int32_t LineCheckSerice(CLine& line);

	void UpdateLinePlayerCount(int32_t line_id, int32_t change_value);

	const TLineMap& GetLineMap() const { return lines_; }

	void set_scene_id(int32_t scene_id) { scene_id_ = scene_id; }
	int32_t scene_id() const { return scene_id_; }

private:
	CSceneConfig scene_config_;
	int32_t GenerateLineId() const;
	TLineMap lines_;
	int32_t scene_id_;
};

typedef std::unordered_map<int32_t, CMainScene>	TMainSceneMap;
class CSceneManager :
	public ::common::CSingleton<CSceneManager>
{
public:

	void OnPlayerChangeScene(Player& player, int32_t scene_id, int32_t line_id);

	void OnPlayerTeleport(Player& player, int32_t target_scene_id, const ::common::CVector3& target_position, float angle, int32_t line_id = 0);

public:
	CSceneManager();
	~CSceneManager();

	bool Initialize();
	bool Finalize();

	CSceneInstance* CreateSceneInstance(int64_t instance_id, int32_t tpl_id, int32_t line_id);
	bool DestorySceneInstance(int64_t instance_id);
	CSceneInstance* GetSceneInstance(int64_t instance_id);


	void TickUpdate();

	static bool PlayerUpdate(::common::CObj& obj, void* param);

	bool TeleportToSpawnPosition(Player& player);

	void Dump();

	int64_t GenerateInstanceId();

	void GateSceneBegin();

	CMainScene* GetMainScene(int32_t scene_id);
	CMainScene* GetMainSceneByinstance(int64_t instance_id);

	CSceneInstance* ChooseScene(int32_t scene_id, int32_t line_id, ::common::CVector3& position, int32_t& error_code);

	// 发给game 提供给客户端场景切换 
	bool ChooseSceneForClient(Player& player, const Json::Value& m_jv);
	bool CheckSceneChange(Player& player, uint32_t scene_id);

	// 自动创建场景
	bool CreateInstanceByTpl();
	// 自动选择场景
	CSceneInstance* AutoChooseScene(int32_t scene_id, ::common::CVector3& dst_pos);


private:
	typedef std::unordered_map<int64_t, OBJ_ID_TYPE> TScenes;

	TScenes scenes_;
	int64_t instance_id_;

	TMainSceneMap main_scene_map_;/**<主场景地图索引  */

	CSceneConfigList sceneconfig_;

	int32_t	last_player_tick_;
};
#endif

